package cn.zurish.cloud.onethread.core.toolkit;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;

import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicLong;

/**
 * 用于构建自定义线程工厂的建造者类，支持设置线程名、优先级、是否为守护线程等属性
 */
public class ThreadFactoryBuilder {

    /**
     * 基础线程工厂，默认使用 Executors.defaultThreadFactory()
     */
    private ThreadFactory backingThreadFactory;
    /**
     * 线程名前缀，如 "onethread-"，线程名形如：onethread-1
     */
    private String namePrefix;
    /**
     * 是否为守护线程，默认 false
     */
    private Boolean daemon;
    /**
     * 线程优先级（1~10）
     */
    private Integer priority;
    /**
     * 未捕获异常处理器
     */
    private Thread.UncaughtExceptionHandler uncaughtExceptionHandler;
    /**
     * 创建 ThreadFactoryBuilder 实例
     */
    public static ThreadFactoryBuilder builder() {
        return new ThreadFactoryBuilder();
    }

    public ThreadFactoryBuilder threadFactory(ThreadFactory backingThreadFactory) {
        this.backingThreadFactory = backingThreadFactory;
        return this;
    }

    public ThreadFactoryBuilder namePrefix(String namePrefix) {
        this.namePrefix = namePrefix;
        return this;
    }

    public ThreadFactoryBuilder daemon(boolean daemon) {
        this.daemon = daemon;
        return this;
    }

    public ThreadFactoryBuilder priority(int priority) {
        if (priority < Thread.MIN_PRIORITY || priority > Thread.MAX_PRIORITY) {
            throw new IllegalArgumentException("Thread priority (which must be an integer " +
                    "in the range " + Thread.MIN_PRIORITY + " to " + Thread.MAX_PRIORITY + ") was " + priority);
        }
        this.priority = priority;
        return this;
    }

    public ThreadFactoryBuilder uncaughtExceptionHandler(Thread.UncaughtExceptionHandler uncaughtExceptionHandler) {
        this.uncaughtExceptionHandler = uncaughtExceptionHandler;
        return this;
    }

    /**
     * 构建线程工厂对象
     *
     * @return 返回配置好的ThreadFactory实例，用于创建具有指定属性的线程
     */
    public ThreadFactory build() {
        // 获取基础线程工厂，如果未指定则使用默认线程工厂
        final ThreadFactory factory = (this.backingThreadFactory != null) ? this.backingThreadFactory : Executors.defaultThreadFactory();
        Assert.notEmpty(namePrefix, "The thread name prefix cannot be empty or an empty string");
        // 如果线程名前缀不为空，则初始化计数器用于生成唯一的线程名称
        final AtomicLong count = (StrUtil.isNotBlank(namePrefix)) ? new AtomicLong(0) : null;

        // 返回自定义的线程工厂Lambda表达式
        return  runnable -> {
            // 使用基础工厂创建新线程
            Thread thread = factory.newThread(runnable);

            // 设置线程名称，如果指定了前缀则添加递增的序号
            if (count != null) {
                thread.setName(namePrefix + count.getAndIncrement());
            }

            // 设置守护线程属性
            if (daemon != null) {
                thread.setDaemon(daemon);
            }

            // 设置线程优先级
            if (priority != null) {
                thread.setPriority(priority);
            }

            // 设置未捕获异常处理器
            if (uncaughtExceptionHandler != null) {
                thread.setUncaughtExceptionHandler(uncaughtExceptionHandler);
            }
            return thread;
        };
    }


}
